package com.sxkj.common.componnet;


import com.sxkj.common.utils.JwtTokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 *
 * @author: daixiaowei
 * @date: 2019年12月07日 下午 02:30:20
 * @description: JWT登录授权过滤器
 */
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    /*
    token = md5(Authorization) 存入redis
     */
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    /*
    包含用户信息的 token(Authorization)
     */
    @Value("${jwt.authHeader}")
    private String authHeader;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Value("${jwt.AccessControlExposeHeaders}")
    private String AccessControlExposeHeaders;

    /**
     *
     * @title: doFilterInternal
     * @author: daixiaowei
     * @date: 2019年12月19日 上午 10:09:09
     * @description: Jwt过滤
     * @param:
     * @return:
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {
        long start = System.currentTimeMillis();
        String authToken = request.getHeader(this.authHeader);
        if (authToken != null) {
            String redisToken = request.getHeader(this.tokenHeader);
           if( redisToken !=null){
               LOGGER.info(redisTemplate.opsForValue().get(redisToken));
           }
            String username = jwtTokenUtil.getUserNameFromToken(authToken);
            LOGGER.info("checking username:{}", username);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                 if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    LOGGER.info("authenticated user:{}", username);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
//         对跨域提供支持
//        response.addHeader("Access-Control-Expose-Headers", "Authorization,Token");
//        String allowHeaders = "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With, Authorization";
        response.addHeader("Access-Control-Expose-Headers", this.AccessControlExposeHeaders);
        response.setHeader("Access-control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
//        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
        chain.doFilter(request, response);
        System.out.println("Execute cost="+(System.currentTimeMillis()-start));
    }

}



